/*

TIME 051851 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE 260112DF
TIME 051851 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE 260112DF
TIME 051851 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE 260112DF
TIME 051851 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE 260112DF
TIME 051854 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE .00012DF
TIME 051854 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE 260112DF */
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdbool.h> 
#include <util/delay.h> 
#include <avr/pgmspace.h>
#include <avr/wdt.h>

#include "Init.h"
#include "nmea.h"
#include"dataflash.h"
#include"usart.h"
#include "I2C.h"
#include"spi.h"
#include"bq32.h"
#define outp(a, b) b = a



unsigned char send_status(void);
void chip_erase(void);
void transmitByte1( unsigned char );
void Term_Send_Value_as_Digits( uint16_t value );
void Term_Send_Value_as_Digits8( uint8_t value );
void PrintNMEABuffer(char* packet);
/*Adding new functions for dataflash*/
void write_flash_string(unsigned char *);
void write_flash(unsigned char );

/*Adding new functions for RTC*/
void gps_rtc_sync(void);
uint8_t bcd(uint8_t );
volatile uint8_t rtc_flag=0;

/* Source of errors will start here */
volatile uint16_t buffer_counter =0;
volatile uint16_t page_counter=0;
/*Values for buffer and page counter, at present using only 1 buffer*/
volatile uint8_t status=0;
volatile uint8_t BuffIndex=0;
char USARTBuffer[80];
char NMEAPacket[80];
char GPGGA[80];//working buffer
//GPGGA data
char   Lat[9];
char Long[10];
char GPSTime[6];
char NS[1];
char EW[1];
char FixQuality;
char Altitude[7];
// GPRMC data
char Speed[5];//in knots
char Heading[5];
char GPSDate[6];
//Flags for some of the functions
volatile uint8_t rtc_set;
uint16_t Average(uint16_t);



int main(void) {
		
		
		cli();
		Init_all();
		spi_init();
		I2CInit();
		//wdt_enable(WDTO_15MS); 
              	DDRE=0xff;
		PORTE=(0<<PE5)|(0<<PE6);
		
		WP_DDR = 0xff;
		WP_PORT = (1<<PD6)|(1<<PD7);//0xff;
		
		//wdt_reset();
		//wdt_disable();
		SPI_PORT &= ~(1<< SPI_CS);
		unsigned char j,k,l;
		j = send_status();
		//wdt_enable(5); 
		while(!((j==0xAC)|(j==0xEC)))
		{
		transmitString1("Error");
		j = send_status();
		}
		//PORTE=(1<<PE5)|(1<<PE6);
		//chip_erase();	
		//wdt_reset();
               // wdt_disable();//500 ms seconds to reach here
		




		transmitString1("WildCense Test");
//transmitByte1('T');	
while (1) {//loop forever
//transmitString1("Entered");
sei();
if ((!status))
{
nmeaProcess();
cli();//Have added this line of code on April 8th did not check the output
if(FixQuality=='1')
{

//wdt_reset();
//wdt_disable();
//cli();
transmitString1("Time");
transmitByte1(' ');
write_flash('&');
for (int i=0;i<6;i++)
{transmitByte1(GPSTime[i]);	

}

transmitByte1(' ');
transmitString1("LAT");
transmitByte1(' ');
for (int i=0;i<9;i++)
{transmitByte1(Lat[i]);

}

transmitByte1(' ');
transmitByte1(NS[0]);
transmitByte1(' ');
transmitString1("LONG");
transmitByte1(' ');
for (int i=0;i<10;i++)
{
transmitByte1(Long[i]);

}
transmitByte1(' ');
transmitByte1(EW[0]);
transmitByte1(' ');
transmitString1("ALT");;
transmitByte1(' ');
for (int i=0;i<7;i++)
{
transmitByte1(Altitude[i]);

}

transmitByte1(' ');
transmitString1("Speed");
transmitByte1(' ');
for (int i=0;i<5;i++)
{
transmitByte1(Speed[i]);

}

transmitByte1(' ');
transmitString1("DIR");;
transmitByte1(' ');
for (int i=0;i<5;i++)
{
transmitByte1(Heading[i]);

}
transmitByte1(' ');
transmitString1("Date");
transmitByte1(' ');
for (uint8_t i=0;i<6;i++)
{
transmitByte1(GPSDate[i]);

}
write_flash_array(GPSTime);
write_flash_array(Lat);
write_flash_array(Long);
write_flash_array(Altitude);
write_flash_array(Speed);
write_flash_array(Heading);
write_flash_array(GPSDate);
rtc_flag++;
gps_rtc_sync();
sei();
}
else
{
wdt_enable(WDTO_1S);

_delay_ms(200);
_delay_ms(200);
transmitByte1('X');
transmitString1(NMEAPacket);
wdt_reset();
wdt_disable();
//wdt_reset();
}
transmitByte1('\r');
transmitByte1('\n');
}
else
{
transmitByte1('N');
//transmitString1("Status");
//wdt_enable(WDTO_8S);
/*for (uint8_t i=0;i<130;i++)
//{
//_delay_ms(100);
}
wdt_reset();
wdt_disable();
*/
}
} 
}



void PrintNMEABuffer(char* packet)
{
int i=0;
while(packet[i]!='*')
{
transmitByte1(packet[i]);
i++;
}

transmitByte1(0xa);
transmitByte1(0xd);


}






//***************************
// Convert byte to 3 ASCII digits and send
//***************************



void Term_Send_Value_as_Digits( uint16_t value )
{
    unsigned char digit;
	
	
    
    digit = '0';
    while( value >= 100 )                // Still larger than 100 ?
    {
        digit++;                         // Increment first digit
        value -= 100;
    }
    
    transmitByte1( digit );                  // Send first digit
    
    digit = '0';
    while( value >= 10 )                 // Still larger than 10 ?
    {
        digit++;                         // Increment second digit
        value -= 10;
    }
    
    transmitByte1( digit );                  // Send second digit
    
    transmitByte1( '0' + value );            // Send third digit
}







void Term_Send_Value_as_Digits8( uint8_t value )
{
    unsigned char digit;
	
	
    
    digit = '0';
    while( value >= 100 )                // Still larger than 100 ?
    {
        digit++;                         // Increment first digit
        value -= 100;
    }
    
    transmitByte1( digit );                  // Send first digit
    
    digit = '0';
    while( value >= 10 )                 // Still larger than 10 ?
    {
        digit++;                         // Increment second digit
        value -= 10;
    }
    
    transmitByte1( digit );                  // Send second digit
    
    transmitByte1( '0' + value );            // Send third digit
}



void write_flash(unsigned char data)
{
if (buffer_counter>528)
{
        
   //Dataflash has 4096 pages, as soon as the buffer 1 gets filled we check the page_counter if that value ia completed, then we again start from page 0.
   //If it not filled it is stored in the page specified by page_counter
   //and page_counter is incremented and buffer_counter is made 0
	if (page_counter>4096) 
	{
	//Do the modular erase and erase the first 100 pages
        //That has not been done yet rather I am overiding the existing pages from 0th page 
	page_counter=0;
	Buffer_To_Page (1,page_counter);
	}
	else
	{
	Buffer_To_Page (1,page_counter);
	page_counter++;
        if(page_counter==0x03)//Making 2 pages to be read
        {
        uint16_t i; uint8_t k,temp;
       for(temp=0;temp<page_counter;temp++)
	{
        // Adding few lines again
        Page_To_Buffer (page_counter, 1);
	
	for( i=0; i<527; i++)

   		{
			//transmitString1("Came");
			k= Buffer_Read_Byte (1, i);
			_delay_ms(100);
			transmitByte1(k);
		}

	buffer_counter = 0;
	}}}//new one is the for loop added for pages
}
else
{
Buffer_Write_Byte (1, buffer_counter, data);
buffer_counter++;
}

}



void write_flash_string(unsigned char *data)
{

   
	while (*data)
        {
	write_flash((unsigned char)*data++);
	//_delay_ms(100);
         }
}

void write_flash_array(unsigned char *data)
{

        unsigned char i= strlen(data);   
	while (i)
        {
	write_flash((unsigned char)*data++);
	//_delay_ms(100);
	i--;
         }
}


void gps_rtc_sync(void)
{
 if(rtc_flag==0x04)
         {
//TIME 051851 LAT 2311.2080 N LONG 07237.6944 E ALT 73.2 SPEED 0.01 DIR 0.00 DATE 260112DF
//All the values that we get serially are being converted into BCD format, if its below 9 same value can be written.Then its written into RTC
	uint8_t sec, min,hours,date,month, year,temp3;
	temp3= 10*GPSTime[0] + 1* GPSTime[1];//Hours
	hours= bcd(temp3);//converting it into BCD format
	temp3 = 10*GPSTime[2] + 1* GPSTime[3];
	min= bcd(temp3);
	temp3 = 10*GPSTime[4] + 1* GPSTime[5];
	sec= bcd(temp3);
	temp3 = 10*GPSDate[0] + 1 * GPSDate[1];
	date= bcd(temp3);	
	temp3 =10*GPSDate[2] + 1 * GPSDate[3];
	month = bcd(temp3);
	temp3 =10*GPSDate[4] + 1 * GPSDate[5];
	year = bcd(temp3);


	temp3 = bq32Write(0x01,min);//In minutes register
	        if(temp3==0)
		{
		transmitString("Not able to write in minutes register");
		}	
	temp3 = bq32Write(0x02,hours);// In hours Register
	        if(temp3==0)
		{
		transmitString("Not able to write in minutes register");
		}
	temp3 = bq32Write(0x03,0x01);// In days Register
	        if(temp3==0)
		{
		transmitString("Not able to write in minutes register");
		}
	temp3 = bq32Write(0x04,date);// In date Register
	        if(temp3==0)
		{
		transmitString("Not able to write in minutes register");
		}
	temp3 = bq32Write(0x05,month);//In  month register
	        if(temp3==0)
		{
		transmitString("Not able to write");
		}
	temp3 = bq32Write(0x06,year);//In  year register
	        if(temp3==0)
		{
		transmitString("Not able to write");
		}	
	temp3 = bq32Write(0x00,sec);//In second register
	        if(temp3==0)
		{
		transmitString("Not able to write");
		}
                transmitString("RTC Written");
}
else{}
}


uint8_t bcd(uint8_t dec)
{
        if(dec>9)
         {
	return ((dec/10)<<4)+(dec%10);
          }
         else
          {
          return dec;
          }
}



